#pragma once

#include "Constants.h"
#include "Mathematics.h"

// Class for managering the camera (position, rotation, FOV etc);
class CameraManager {
public:
// ctor
	CameraManager(u32 w = BASE_WIDTH, u32 h = BASE_HEIGHT, fp32 fov = BASE_FOV);
	~CameraManager() {};

// singletone getter
	static inline CameraManager &instance () {
		static CameraManager camera;
		return camera;
	}

//	getters
	inline const Vector3f &pos () const { return _pos; }
	inline const Vector3f &dir () const { return _target; }
	inline const Vector3f &up () const { return _up; }

	void update ();
	void onRender ();

//	setters
	inline void pos (const Vector3f &v) { _pos = v; }
	inline void target (const Vector3f &v) { _target = v; _target.nrm(); }
	inline void up (const Vector3f &v) { _up = v; _up.nrm(); }

	inline void setAll (const Vector3f &p, const Vector3f &t, const Vector3f &u) { pos(p); target(t); up(u); }

//	transformations
	inline const Matrix_4x4 &cameraTranslation () { return initCameraTranslation(); }
	inline const Matrix_4x4 &cameraRotation () { return initCameraRotation(); }

//	hadlers
	bool keyboardHandler (unsigned char Key);
	void mouseHandler ();

	bool need_mouse_update () { return _need_mouse_update; }
	void need_mouse_update (bool v) { _need_mouse_update = v; }

private:
	void init ();

	const Matrix_4x4 &initCameraTranslation ();
	const Matrix_4x4 &initCameraRotation ();

private:
	u32 _window_width;
	u32 _window_height;

	fp32 _angle_h;
	fp32 _angle_v;

	Vector2i _mouse_pos;
	bool _need_mouse_update;

	Vector3f _pos;
	Vector3f _target;
	Vector3f _up;

	Matrix_4x4 _camera_translation;
	Matrix_4x4 _camera_rotation;
};